package com.uyayo.cms.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uyayo.cms.dto.CmsArticleDTO;
import com.uyayo.cms.entity.*;
import com.uyayo.cms.mapper.*;
import com.uyayo.cms.model.CmsArticleCondition;
import com.uyayo.cms.model.CmsArticleCountBO;
import com.uyayo.cms.service.CmsArticleService;
import com.uyayo.cms.utils.Html2TextUtil;
import com.uyayo.framework.pagehelper.pojo.OrderBy;
import com.uyayo.framework.pagehelper.pojo.PageBean;
import com.uyayo.framework.pagehelper.util.OrderByUtil;
import org.apache.commons.beanutils.ConvertUtils;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("cmsArticleService")
public class CmsArticleServiceImpl implements CmsArticleService {


	private final CmsArticleMapper cmsArticleMapper;

	private final CmsArticleLikeMapper cmsArticleLikeMapper;

	private final DozerBeanMapper dozerBeanMapper;

	private final CmsArticleCategoryRelMapper cmsArticleCategoryRelMapper;

	private final CmsArticleTagRelMapper cmsArticleTagRelMapper;

	private final CmsTagMapper cmsTagMapper;


	@Autowired
	public CmsArticleServiceImpl(CmsArticleMapper cmsArticleMapper, CmsArticleLikeMapper cmsArticleLikeMapper, DozerBeanMapper dozerBeanMapper, CmsArticleCategoryRelMapper cmsArticleCategoryRelMapper, CmsArticleTagRelMapper cmsArticleTagRelMapper, CmsTagMapper cmsTagMapper) {
		this.cmsArticleMapper = cmsArticleMapper;
		this.cmsArticleLikeMapper = cmsArticleLikeMapper;
		this.dozerBeanMapper = dozerBeanMapper;
		this.cmsArticleCategoryRelMapper = cmsArticleCategoryRelMapper;
		this.cmsArticleTagRelMapper = cmsArticleTagRelMapper;
		this.cmsTagMapper = cmsTagMapper;
	}


	@Override
	public CmsArticle getArticleById(Long id){
		return cmsArticleMapper.selectByPrimaryKey(id);
	}
	

	@Override
	public List<CmsArticle> selectArticle(CmsArticleCondition cmsArticleCondition) {
		Example example = new Example(CmsArticle.class);
		example.createCriteria();
		return cmsArticleMapper.selectByExample(example);
	}
	
	@Override
	public PageBean<CmsArticle> selectArticleByPaging(Integer pageCurrent, Integer pageSize, String sort, String order, CmsArticleCondition cmsArticleCondition) {

		List<CmsArticle> userList;
		//分页处理
		List<OrderBy> orderBies = new ArrayList<>();
		orderBies.add(new OrderBy("createTime", "create_time"));
		orderBies.add(new OrderBy("updateTime", "update_time"));
		orderBies.add(new OrderBy("viewCount", "view_count"));

		OrderByUtil  orderByUtil = new OrderByUtil();
		String orderBy = orderByUtil.getOrderBy(orderBies, sort, order);
		PageHelper.startPage(pageCurrent, pageSize);
		
		Example example = new Example(CmsArticle.class);
		if(!StringUtils.isEmpty(orderBy)){
			example.setOrderByClause(orderBy);
		}
		Criteria criteria = example.createCriteria();
		if(!StringUtils.isEmpty(cmsArticleCondition.getTitle())){
			criteria.andLike("title","%"+cmsArticleCondition.getTitle()+"%");
		}
		if(Objects.nonNull(cmsArticleCondition.getChannelId())){
			criteria.andEqualTo("channelId",cmsArticleCondition.getChannelId());
		}
		if(Objects.nonNull(cmsArticleCondition.getMemberId())){
			criteria.andEqualTo("memberId",cmsArticleCondition.getMemberId());
		}
		if(cmsArticleCondition.getBeginCreatedTime()!=null || cmsArticleCondition.getEndCreatedTime()!=null){
			criteria.andBetween("createTime", cmsArticleCondition.getBeginCreatedTime(), cmsArticleCondition.getEndCreatedTime());
		}
		userList = cmsArticleMapper.selectByExample(example);

		//取记录总条数
		PageInfo<CmsArticle> pageInfo = new PageInfo<>(userList);
		
		return new PageBean<>(pageInfo.getTotal(), pageCurrent, pageSize, userList);
	}

	@Override
	public CmsArticle getAfterArticle(Long id,Long channelId) {
		Example example = new Example(CmsArticle.class);
		Criteria criteria = example.createCriteria();
		criteria.andGreaterThan("id",id);
		criteria.andEqualTo("channelId",channelId);
		CmsArticle cmsArticle = new CmsArticle();
		List<CmsArticle> cmsArticles= cmsArticleMapper.selectByExample(example);
		if(cmsArticles.size() > 0 ){
			cmsArticle = cmsArticles.get(0);
		}else{
			cmsArticle.setTitle("这是最后一篇文章");
			cmsArticle.setId(id);
		}
		return cmsArticle;
	}

	@Override
	public CmsArticle getPrevArticle(Long id,Long channelId) {
		Example example = new Example(CmsArticle.class);
		Criteria criteria = example.createCriteria();
		criteria.andLessThan("id",id);
		criteria.andEqualTo("channelId",channelId);
		CmsArticle cmsArticle = new CmsArticle();
		List<CmsArticle> cmsArticles= cmsArticleMapper.selectByExample(example);

		if(cmsArticles.size() > 0 ){
			cmsArticle = cmsArticles.get(0);
		}else{
			cmsArticle.setTitle("这是第一篇文章");
			cmsArticle.setId(id);
		}
		return cmsArticle;
	}

	@Override
	public int createCmsArticle(CmsArticleDTO cmsArticleDTO) {
		CmsArticle cmsArticle = dozerBeanMapper.map(cmsArticleDTO, CmsArticle.class);
		if(org.apache.commons.lang3.StringUtils.isBlank(cmsArticleDTO.getDescription())){
			cmsArticleDTO.setDescription(Html2TextUtil.getDescription(cmsArticleDTO.getContent(),100));
		}
		if(org.apache.commons.lang3.StringUtils.isBlank(cmsArticleDTO.getKeywords())) {
			Example exampleO = new Example(CmsTag.class);
			Example.Criteria criteriaO = exampleO.createCriteria();
			Long[] articleTagIdArr = (Long[]) ConvertUtils.convert(cmsArticleDTO.getTagIds().split(","),Long.class);
			List<Long> tagList= Arrays.asList(articleTagIdArr);
			criteriaO.andIn("id", tagList);
			List<CmsTag>  cmsTags= cmsTagMapper.selectByExample(exampleO);
			List<String> list = cmsTags.stream().map(CmsTag::getName).collect(Collectors.toList());
			cmsArticleDTO.setKeywords(org.apache.commons.lang3.StringUtils.join(list.toArray(), ","));
		}
		int count = cmsArticleMapper.insertSelective(cmsArticle);
		insertArticleCategoryRelByList(cmsArticleDTO.getArticleCategoryIds(),cmsArticle.getId());
		insertArticleTagRelByList(cmsArticleDTO.getTagIds(), cmsArticle.getId());
		return count;
	}



	public void insertArticleCategoryRelByList(String articleCategoryIds, Long articleId) {

		Example exampleO = new Example(CmsArticleCategoryRel.class);
		Example.Criteria criteriaO = exampleO.createCriteria();
		criteriaO.andEqualTo("articleId", articleId);
		cmsArticleCategoryRelMapper.deleteByExample(exampleO);
		//转换long类型的数组
		Long[] articleCategoryIdArr = (Long[]) ConvertUtils.convert(articleCategoryIds.split(","),Long.class);
		if(articleCategoryIdArr.length>0 && articleCategoryIdArr[0]!=null){
			for (Long articleCategoryId : articleCategoryIdArr) {
				CmsArticleCategoryRel cmsArticleCategoryRel = new CmsArticleCategoryRel();
				cmsArticleCategoryRel.setArticleId(articleId);
				cmsArticleCategoryRel.setCategoryId(articleCategoryId);
				cmsArticleCategoryRelMapper.insertSelective(cmsArticleCategoryRel);
			}
		}
	}

	public void insertArticleTagRelByList(String articleTagIds, Long articleId) {

		Example exampleO = new Example(CmsArticleTagRel.class);
		Example.Criteria criteriaO = exampleO.createCriteria();
		criteriaO.andEqualTo("articleId", articleId);
		cmsArticleTagRelMapper.deleteByExample(exampleO);
		//转换long类型的数组
		Long[] articleTagIdArr = (Long[]) ConvertUtils.convert(articleTagIds.split(","),Long.class);
		if(articleTagIdArr.length>0 && articleTagIdArr[0]!=null){
			for (Long articleTagId : articleTagIdArr) {
				CmsArticleTagRel cmsArticleTagRel = new CmsArticleTagRel();
				cmsArticleTagRel.setArticleId(articleId);
				cmsArticleTagRel.setTagId(articleTagId);
				cmsArticleTagRelMapper.insertSelective(cmsArticleTagRel);
			}
		}
	}

	@Override
	public CmsArticle selectOne(CmsArticle cmsArticle) {
		return cmsArticleMapper.selectOne(cmsArticle);
	}

	@Override
	public int updateArticle(CmsArticleDTO cmsArticleDTO) {
		CmsArticle cmsArticle = dozerBeanMapper.map(cmsArticleDTO, CmsArticle.class);
		if(org.apache.commons.lang3.StringUtils.isBlank(cmsArticleDTO.getDescription())){
			cmsArticle.setDescription(Html2TextUtil.getDescription(cmsArticleDTO.getContent(),100));
		}
		if(org.apache.commons.lang3.StringUtils.isBlank(cmsArticleDTO.getKeywords())) {
			Example exampleO = new Example(CmsTag.class);
			Example.Criteria criteriaO = exampleO.createCriteria();
			Long[] articleTagIdArr = (Long[]) ConvertUtils.convert(cmsArticleDTO.getTagIds().split(","),Long.class);
			List<Long> tagList= Arrays.asList(articleTagIdArr);
			criteriaO.andIn("id", tagList);
			List<CmsTag>  cmsTags= cmsTagMapper.selectByExample(exampleO);
			List<String> list = cmsTags.stream().map(CmsTag::getName).collect(Collectors.toList());
			cmsArticle.setKeywords(org.apache.commons.lang3.StringUtils.join(list.toArray(), ","));
		}
		int count = cmsArticleMapper.updateByPrimaryKeySelective(cmsArticle);
		insertArticleCategoryRelByList(cmsArticleDTO.getArticleCategoryIds(),cmsArticle.getId());
		insertArticleTagRelByList(cmsArticleDTO.getTagIds(), cmsArticle.getId());
		return count;
	}

	@Override
	public int deleteArticle(Long id) {
		return cmsArticleMapper.deleteByPrimaryKey(id);
	}



	@Override
	public int updateArticleCount(CmsArticleCountBO cmsArticleCountBO) {
		CmsArticle cmsArticle = new CmsArticle();
		cmsArticle.setId(cmsArticleCountBO.getId());
		cmsArticle = this.selectOne(cmsArticle);
		if(Objects.nonNull(cmsArticleCountBO.getClickCount())){
			cmsArticle.setClickCount(cmsArticle.getClickCount()+cmsArticleCountBO.getClickCount());
		}
		if(Objects.nonNull(cmsArticleCountBO.getCollectionCount())){
			cmsArticle.setCollectionCount(cmsArticle.getCollectionCount()+cmsArticleCountBO.getCollectionCount());
		}
		if(Objects.nonNull(cmsArticleCountBO.getCommentCount())){
			cmsArticle.setCommentCount(cmsArticle.getCommentCount()+cmsArticleCountBO.getCommentCount());
		}
		if(Objects.nonNull(cmsArticleCountBO.getLikeCount())){
			cmsArticle.setLikeCount(cmsArticle.getLikeCount()+cmsArticleCountBO.getLikeCount());
		}
		if(Objects.nonNull(cmsArticleCountBO.getDislikeCount())){
			cmsArticle.setDislikeCount(cmsArticle.getDislikeCount()+cmsArticleCountBO.getDislikeCount());
		}
		if(Objects.nonNull(cmsArticleCountBO.getShareCount())){
			cmsArticle.setShareCount(cmsArticle.getShareCount()+cmsArticleCountBO.getShareCount());
		}
		if(Objects.nonNull(cmsArticleCountBO.getViewCount())){
			cmsArticle.setViewCount(cmsArticle.getViewCount()+cmsArticleCountBO.getViewCount());
		}
		return cmsArticleMapper.updateByPrimaryKeySelective(cmsArticle);
	}


	@Override
	public int like(CmsArticleLike cmsArticleLike) {
		CmsArticleLike cmsLikeCondition = new CmsArticleLike();
		cmsLikeCondition.setArticleId(cmsArticleLike.getArticleId());
		cmsLikeCondition.setLikeType(cmsArticleLike.getLikeType());
		cmsLikeCondition.setMemberId(cmsArticleLike.getMemberId());
		List<CmsArticleLike> cmsArticleLikeList = cmsArticleLikeMapper.select(cmsLikeCondition);
		if(cmsArticleLikeList != null && cmsArticleLikeList.size()==1){//查询出数据才进行下一步
			CmsArticleLike cmsArticleLikeDB = cmsArticleLikeList.get(0);
			if(cmsArticleLikeList.get(0).getStatus().equals(cmsArticleLike.getStatus())){ //状态和数据库里的相同则无需处理
				return 0;
			}

			CmsArticleCountBO cmsArticleCountBO = new CmsArticleCountBO();
			cmsArticleCountBO.setId(cmsArticleLike.getArticleId());
			if(cmsArticleLike.getLikeType()==1 && cmsArticleLike.getStatus()==0){ //取消赞
				cmsArticleLikeDB.setStatus((short) 0);
				cmsArticleCountBO.setLikeCount(-1);
				this.updateArticleCount(cmsArticleCountBO);
			}else if(cmsArticleLike.getLikeType()==1 && cmsArticleLike.getStatus()==1){	//赞
				cmsArticleLikeDB.setStatus((short) 1);
				cancelDislike(cmsArticleLike.getArticleId(),cmsArticleLike.getMemberId());
			}else if(cmsArticleLike.getLikeType()==2 && cmsArticleLike.getStatus()==0){	//取消踩
				cmsArticleLikeDB.setStatus((short) 0);
				cmsArticleCountBO.setDislikeCount(-1);
				this.updateArticleCount(cmsArticleCountBO);
			}else {	//踩(cmsArticleLike.getLikeType()==2 && cmsArticleLike.getStatus()==1)
				cmsArticleLikeDB.setStatus((short) 1);
				cancelLike(cmsArticleLike.getArticleId(),cmsArticleLike.getMemberId());
			}
			return  this.cmsArticleLikeMapper.updateByPrimaryKeySelective(cmsArticleLikeDB);
		}else{
			if(cmsArticleLike.getLikeType()==2){
				cancelLike(cmsArticleLike.getArticleId(),cmsArticleLike.getMemberId());
			}else {
				cancelDislike(cmsArticleLike.getArticleId(),cmsArticleLike.getMemberId());
			}
			return cmsArticleLikeMapper.insertSelective(cmsArticleLike);
		}
	}

	/**
	 * 取消赞
	 * @param articleId 文章ID
	 * @param memberId 会员ID
	 */
	private void cancelLike(Long articleId,Long memberId){
		CmsArticleLike cmsDisLikeOppositeCondition = new CmsArticleLike();
		cmsDisLikeOppositeCondition.setArticleId(articleId);
		cmsDisLikeOppositeCondition.setLikeType((short) 1);
		cmsDisLikeOppositeCondition.setMemberId(memberId);
		CmsArticleLike cmsArticleDisLikeOppositeDB = cmsArticleLikeMapper.selectOne(cmsDisLikeOppositeCondition);
		if(cmsArticleDisLikeOppositeDB!=null  && cmsArticleDisLikeOppositeDB.getStatus()==1){
			cmsArticleDisLikeOppositeDB.setStatus((short) 0);
			this.cmsArticleLikeMapper.updateByPrimaryKeySelective(cmsArticleDisLikeOppositeDB);

			//文章的赞数量-1
			CmsArticleCountBO cmsArticleDisLikeCountOppositeBO = new CmsArticleCountBO();
			cmsArticleDisLikeCountOppositeBO.setId(articleId);
			cmsArticleDisLikeCountOppositeBO.setLikeCount(-1);
			this.updateArticleCount(cmsArticleDisLikeCountOppositeBO);
		}

		//文章的踩数量+1
		CmsArticleCountBO cmsArticleCountBO = new CmsArticleCountBO();
		cmsArticleCountBO.setId(articleId);
		cmsArticleCountBO.setDislikeCount(1);
		this.updateArticleCount(cmsArticleCountBO);
	}

	/**
	 * 取消踩
	 * @param articleId 文章ID
	 * @param memberId 会员ID
	 */
	private void cancelDislike(Long articleId,Long memberId){
		//取消踩
		CmsArticleLike cmsLikeOppositeCondition = new CmsArticleLike();
		cmsLikeOppositeCondition.setArticleId(articleId);
		cmsLikeOppositeCondition.setLikeType((short) 2);
		cmsLikeOppositeCondition.setMemberId(memberId);
		CmsArticleLike cmsArticleLikeOppositeDB = cmsArticleLikeMapper.selectOne(cmsLikeOppositeCondition);
		if(cmsArticleLikeOppositeDB!=null  && cmsArticleLikeOppositeDB.getStatus()==1){
			cmsArticleLikeOppositeDB.setStatus((short) 0);
			this.cmsArticleLikeMapper.updateByPrimaryKeySelective(cmsArticleLikeOppositeDB);

			//文章的踩数量-1
			CmsArticleCountBO cmsArticleLikeCountOppositeBO = new CmsArticleCountBO();
			cmsArticleLikeCountOppositeBO.setId(articleId);
			cmsArticleLikeCountOppositeBO.setDislikeCount(-1);
			this.updateArticleCount(cmsArticleLikeCountOppositeBO);
		}

		//文章的赞数量+1
		CmsArticleCountBO cmsArticleCountBO = new CmsArticleCountBO();
		cmsArticleCountBO.setId(articleId);
		cmsArticleCountBO.setLikeCount(1);
		this.updateArticleCount(cmsArticleCountBO);
	}
}
